/*
 * Copyright 2008 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.dev.javac.impl;

/**
 * Contains standard Java source files for testing.
 */
public class JavaResourceBase {

  public static final MockResource ANNOTATION = new MockJavaResource(
      "java.lang.annotation.Annotation") {
    @Override
    protected CharSequence getContent() {
      StringBuffer code = new StringBuffer();
      code.append("package java.lang.annotation;\n");
      code.append("public interface Annotation {\n");
      code.append("}\n");
      return code;
    }
  };
  public static final MockJavaResource BAR = new MockJavaResource("test.Bar") {
    @Override
    protected CharSequence getContent() {
      StringBuffer code = new StringBuffer();
      code.append("package test;\n");
      code.append("public class Bar extends Foo {\n");
      code.append("  public String value() { return \"Bar\"; }\n");
      code.append("}\n");
      return code;
    }
  };
  public static final MockResource CLASS = new MockJavaResource(
      "java.lang.Class") {
    @Override
    protected CharSequence getContent() {
      StringBuffer code = new StringBuffer();
      code.append("package java.lang;\n");
      code.append("public class Class<T> {\n");
      code.append("  static <T> Class<T> createForClass(String p, String c, Class<? super T> s) {");
      code.append("    return new Class<T>();");
      code.append("  }");
      code.append("  public boolean desiredAssertionStatus() { return false; }");
      code.append("  public String getName() { return \"classname\"; }");
      code.append("  public Class getSuperclass() { return new Class(); }");
      code.append("  public static <T> Class<T> createForArray("
                  + "String pkg, String clz) { return new Class<T>(); }");
      code.append("  static Class<?> createForPrimitive("
                  + "String pkg, String className) { return new Class(); }");
      code.append("}\n");
      return code;
    }
  };
  public static final MockJavaResource FOO = new MockJavaResource("test.Foo") {
    @Override
    protected CharSequence getContent() {
      StringBuffer code = new StringBuffer();
      code.append("package test;\n");
      code.append("public class Foo {\n");
      code.append("  public String value() { return \"Foo\"; }\n");
      code.append("}\n");
      return code;
    }
  };
  public static final MockResource JAVASCRIPTOBJECT = new MockJavaResource(
      "com.google.gwt.core.client.JavaScriptObject") {
    @Override
    protected CharSequence getContent() {
      StringBuffer code = new StringBuffer();
      code.append("package com." + "google.gwt.core.client;\n");
      code.append("public class JavaScriptObject {\n");
      code.append("  protected JavaScriptObject() {}\n");
      code.append("  public final boolean equals(Object that){ return false;}");
      code.append("  public int hashCode(){return 0;}");
      code.append("}\n");
      return code;
    }
  };
  public static final MockResource MAP = new MockJavaResource("java.util.Map") {
    @Override
    protected CharSequence getContent() {
      StringBuffer code = new StringBuffer();
      code.append("package java.util;\n");
      code.append("public interface Map<K,V> { }\n");
      return code;
    }
  };
  public static final MockResource OBJECT = new MockJavaResource(
      "java.lang.Object") {
    @Override
    protected CharSequence getContent() {
      StringBuffer code = new StringBuffer();
      code.append("package java.lang;\n");
      code.append("public class Object {\n");
      code.append("  public String toString() { return \"Object\"; }\n");
      code.append("  public int hashCode() { return 0; }\n");
      code.append("  public boolean equals(Object that){return this == that;}");
      code.append("  public static boolean magic_equals(Object self, Object other) {");
      code.append("    return self == other;");
      code.append("  }");
      code.append("  public static Class magic_getClass(Object self) {");
      code.append("    return Object.class;");
      code.append("  }");
      code.append("  public static int magic_hashCode(Object self) {");
      code.append("    return 0;");
      code.append("  }");
      code.append("  public static String magic_toString(Object self) {");
      code.append("    return \"\";");
      code.append("  }");
      code.append("}\n");
      return code;
    }
  };
  public static final MockResource SERIALIZABLE = new MockJavaResource(
      "java.io.Serializable") {
    @Override
    protected CharSequence getContent() {
      StringBuffer code = new StringBuffer();
      code.append("package java.io;\n");
      code.append("public interface Serializable { }\n");
      return code;
    }
  };
  public static final MockResource STRING = new MockJavaResource(
      "java.lang.String") {
    @Override
    protected CharSequence getContent() {
      StringBuffer code = new StringBuffer();
      code.append("package java.lang;\n");
      code.append("import java.io.Serializable;\n");
      code.append("public final class String implements Serializable {\n");
      code.append("  private static final long serialVersionUID = 0L;\n");
      code.append("  public int length() { return 0; }\n");
      code.append("}\n");
      return code;
    }
  };
  public static final MockResource SUPPRESS_WARNINGS = new MockJavaResource(
      "java.lang.SuppressWarnings") {
    @Override
    protected CharSequence getContent() {
      StringBuffer code = new StringBuffer();
      code.append("package java.lang;\n");
      code.append("public @interface SuppressWarnings {\n");
      code.append("  String[] value();\n");
      code.append("}\n");
      return code;
    }
  };

  private static MockResource[] standardResources = new MockResource[] {
    ANNOTATION, CLASS, JAVASCRIPTOBJECT, MAP,
    OBJECT, SERIALIZABLE, STRING, SUPPRESS_WARNINGS,
    make("com.google.gwt.core.client.AsyncFragmentLoader"),
    make("com.google.gwt.core.client.GWT",
         "static boolean isClient() {return true;}"
         + "static boolean isScript() { return true; }"
         + "static Object create() { return null; }"),
    make("com.google.gwt.core.client.RunAsyncCallback"),
    make("com.google.gwt.lang.ClassLiteralHolder"),
    make("com.google.gwt.lang.EntryMethodHolder"),
    make("com.google.gwt.lang.Exceptions",
         "static void caught(Object e) {}"),
    make("com.google.gwt.lang.LongLib",
         "public static String toString(long l) { return \"\"; }"),
    make("com.google.gwt.lang.Stats",
         "static boolean isStatsAvailable() { return false; }"
         + "static void onModuleStart() { }"),
    make("com.google.gwt.core.client.Object"),
    make("java.io.ObjectOutputStream"),
    make("java.io.ObjectInputStream"),
    make("com.google.gwt.lang.Array",
         "static void setCheck(Array array, int index, Object value) {}"
         + "static void initDim(Class arrayClass, int typeId, int queryId, "
             + "int length, int seedType) {}"
         + "static void initDims(Class arrayClasses[], int[] typeIdExprs, "
             + "int[] queryIdExprs, int[] dimExprs, int count, int seedType) {}"
         + "static void initValues(Class arrayClass, int typeId, int queryId, "
             + "Array array) {}"),
    make("com.google.gwt.lang.Cast",
         "boolean isJavaObject() { return true; }"
         + "static boolean instanceOf(Object src, int dstId) { return true; }"
         + "static int narrow_int(double d) { return 0; }"
         + "static String charToString(char c) { return \"\"; }"),
    make("java.lang.Exception", "", "public class", "extends Throwable"),
    make("java.lang.IndexOutOfBoundsException",
        "", "public class", "extends Exception"),
    make("java.lang.Throwable"),
    make("java.lang.CharSequence", "", "public interface"),
    make("java.lang.Comparable", "", "public interface"),
    make("java.lang.Iterable", "", "public interface"),
    make("java.lang.Enum"),
    make("java.util.Iterator", "", "public interface"),
  };

  public static MockResource[] getStandardResources() {
    return standardResources;
  }

  /** Returns a mock java source file with an empty implementation. */
  private static MockResource make(String className) {
    return make(className, "");
  }

  private static MockResource make(String className, String methods) {
    return make(className, methods, "public class ");
  }

  private static MockResource make(String className, String methods,
      String qualifiers) {
    return make(className, methods, qualifiers, "");
  }

  private static MockResource make(final String className, final String methods,
      final String qualifiers, final String extnds) {
    return new MockJavaResource(className) {
      @Override protected CharSequence getContent() {
        String pkg = className.substring(0, className.lastIndexOf('.'));
        String shortClass = className.substring(className.lastIndexOf('.') + 1);
        String code = ""
            + "package " +  pkg + ";\n"
            + qualifiers + " " + shortClass + " " + extnds + " {\n"
            + methods
            + "}\n";
        return code;
      }
    };
  }
}
